﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Text.RegularExpressions;

namespace wojilu
{
    /// <summary>
    /// 扩展方法类 链式编程 2012-09-01 berin
    /// </summary>
    public static class ExpandUtility
    {
        #region DataTable扩展


        public static IList<T> FillEntityFromReader<T>(SqlDataReader reader)
        {
            List<T> list = new List<T>();
            List<PropertyInfo> pinfoList = new List<PropertyInfo>();
            Boolean checkedPropertyInfo = false;
            while (reader.Read())
            {
                T instance = Activator.CreateInstance<T>();

                #region 检查数据库字段与实体类属性的匹配情况
                if (!checkedPropertyInfo)
                {
                    foreach (PropertyInfo pinfo in typeof(T).GetProperties())
                    {
                        //判断reader是否有此Property中的BoundFieldAttribute所对应需要绑定的字段
                        if (reader.GetSchemaTable().Select("ColumnName='" + pinfo.Name + "'").Length > 0)
                        {
                            pinfoList.Add(pinfo);
                        }
                    }
                }
                #endregion

                //查检完成
                checkedPropertyInfo = true;

                //开始赋值
                foreach (PropertyInfo info in pinfoList)
                {
                    int index = reader.GetOrdinal(info.Name);
                    if (reader.GetValue(index) != DBNull.Value)
                    {
                        if (!info.PropertyType.IsEnum)
                        {
                            info.SetValue(instance, Convert.ChangeType(reader.GetValue(index), info.PropertyType), null);
                        }
                        else
                        {
                            info.SetValue(instance, Enum.Parse(info.PropertyType, reader.GetValue(index).ToString()), null);
                        }
                    }
                }

                list.Add(instance);
            }
            reader.Close();
            return list;
        }

        /// <summary>
        /// 此方法适应与数据表结构字母大小写和实体类属性名称相同的情况下
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static List<T> FillEntityFromDatatable<T>(this DataTable dt) where T : new()
        {
            var list = new List<T>();
            if (dt == null) return list;
            var len = dt.Rows.Count;

            for (var i = 0; i < len; i++)
            {
                var info = new T();
                foreach (DataColumn dc in dt.Rows[i].Table.Columns)
                {
                    var value = dt.Rows[i][dc.ColumnName];
                    if (value == null || string.IsNullOrEmpty(value.ToString())) continue;

                    // var mName=info.GetType().GetProperties()

                    var p = info.GetType().GetProperty(dc.ColumnName);


                    try
                    {
                        if (p.PropertyType == typeof(string))
                        {
                            p.SetValue(info, value.ToString(), null);
                        }
                        else if (p.PropertyType == typeof(int))
                        {
                            p.SetValue(info, int.Parse(value.ToString()), null);
                        }
                        else if (p.PropertyType == typeof(bool))
                        {
                            p.SetValue(info, bool.Parse(value.ToString()), null);
                        }
                        else if (p.PropertyType == typeof(DateTime))
                        {
                            p.SetValue(info, DateTime.Parse(value.ToString()), null);
                        }
                        else if (p.PropertyType == typeof(float))
                        {
                            p.SetValue(info, float.Parse(value.ToString()), null);
                        }
                        else if (p.PropertyType == typeof(double))
                        {
                            p.SetValue(info, double.Parse(value.ToString()), null);
                        }
                        else
                        {
                            p.SetValue(info, value.ToString(), null);
                        }
                    }
                    catch (Exception)
                    {
                        //p.SetValue(info, ex.Message, null);
                    }
                }
                list.Add(info);
            }
            dt.Dispose(); dt = null;
            return list;
        }

        /// <summary>
        /// table转实体对象扩展方法，不区分数据表列名称大小写
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static List<T> ToList<T>(this DataTable dt) where T : new()
        {
            var list = new List<T>();
            if (dt == null) return list;
            var len = dt.Rows.Count;

            for (var i = 0; i < len; i++)
            {
                var info = new T();

                for (int j = 0; j < dt.Rows[i].Table.Columns.Count; j++)
                {
                    DataColumn dc = dt.Rows[i].Table.Columns[j];

                    //数据表列名称
                    var CName = dc.ColumnName.ToLower();
                    var value = dt.Rows[i][CName];
                    if (value == null || string.IsNullOrEmpty(value.ToString())) continue;
                    var p = info.GetType().GetProperty(CName);
                    var ps = info.GetType().GetProperties();

                    for (int k = 0; k < ps.Length; k++)
                    {
                        //实体类属性名称
                        var Mname = ps[k].Name.ToLower();
                        if (CName == Mname)
                        {
                            p = ps[k];
                            break;
                        }
                    }
                    try
                    {
                        if (p.PropertyType == typeof(string))
                        {
                            p.SetValue(info, value.ToString(), null);
                        }
                        else if (p.PropertyType == typeof(int))
                        {
                            p.SetValue(info, int.Parse(value.ToString()), null);
                        }
                        else if (p.PropertyType == typeof(bool))
                        {
                            p.SetValue(info, bool.Parse(value.ToString()), null);
                        }
                        else if (p.PropertyType == typeof(DateTime))
                        {
                            p.SetValue(info, DateTime.Parse(value.ToString()), null);
                        }
                        else if (p.PropertyType == typeof(float))
                        {
                            p.SetValue(info, float.Parse(value.ToString()), null);
                        }
                        else if (p.PropertyType == typeof(double))
                        {
                            p.SetValue(info, double.Parse(value.ToString()), null);
                        }
                        else
                        {
                            p.SetValue(info, value.ToString(), null);
                        }
                    }
                    catch (Exception)
                    {
                        //p.SetValue(info, ex.Message, null);
                    }


                }
                list.Add(info);
            }
            dt.Dispose(); dt = null;
            return list;
        }

        /// <summary>
        /// 按照属性顺序的列名集合
        /// </summary>
        public static IList<string> GetColumnNames(this DataTable dt)
        {
            DataColumnCollection dcc = dt.Columns;
            //由于集合中的元素是确定的，所以可以指定元素的个数，系统就不会分配多余的空间，效率会高点
            IList<string> list = new List<string>(dcc.Count);
            foreach (DataColumn dc in dcc)
            {
                list.Add(dc.ColumnName);
            }
            return list;
        }

        #endregion


        #region String扩展

        /// <summary>
        /// 扩展方法String转换int
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static int ToInt(this string s)
        {
            int id;
            int.TryParse(s, out id);//这里当转换失败时返回的id为0
            return id;
        }

        /// <summary>
        /// 扩展方法String转换DateTime
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this string s)
        {
            DateTime dt;
            DateTime.TryParse(s, out dt);
            return dt;
        }

        /// <summary>
        /// 判断字符串是否为空
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string s)
        {
            return string.IsNullOrEmpty(s);
        }

        /// <summary>
        /// 判断是否为正整数
        /// </summary>
        /// <param name="inString"></param>
        /// <returns></returns>
        public static bool IsInt(this string inString)
        {
            System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("^[0-9]*[1-9][0-9]*$");
            return regex.IsMatch(inString.Trim());
        }


        /// <summary>
        /// 如果字符串是文件路径或者url可以使用此扩展方法
        /// </summary>
        /// <param name="s"></param>
        public static string Open(this string s)
        {
            System.Diagnostics.Process.Start(s);
            return s;
        }

        /// <summary>
        /// 截取字符串，超出部分显示...
        /// </summary>
        /// <param name="str"></param>
        /// <param name="maxlength"></param>
        /// <returns></returns>
        public static string CutString(this string str, int maxlength)
        {
            if (str.Length > maxlength)
                return str.Substring(0, maxlength) + "...";
            else return str;
        }


        #endregion


        #region Page页面扩展

        /// <summary>
        /// 执行JavaScript脚本方法
        /// </summary>
        /// <param name="script"></param>
        public static void JavascriptFun(this System.Web.UI.Page page, string script)
        {
            string AllScript = string.Format("<script>{0}</script>", script);
            page.ClientScript.RegisterStartupScript(page.GetType(), System.Guid.NewGuid().ToString(), AllScript);
        }


        /// <summary>
        /// 显示提示消息并跳转页面
        /// </summary>
        /// <param name="message">提示消息内容</param>
        /// <param name="url">跳转url</param>
        public static void ShowMsg(this System.Web.UI.Page page, string message, string url)
        {
            string script = string.Format("<script>alert('{0}');location.href='{1}';</script>", message, url);
            page.ClientScript.RegisterStartupScript(page.GetType(), System.Guid.NewGuid().ToString(), script);
        }

        /// <summary>
        /// 显示提示消息
        /// </summary>
        /// <param name="message">提示消息内容</param>
        public static void ShowMsg(this System.Web.UI.Page page, string message)
        {
            string script = string.Format("<script>alert('{0}');</script>", message);
            page.ClientScript.RegisterStartupScript(page.GetType(), System.Guid.NewGuid().ToString(), script);
        }


        /// <summary>
        /// 获得传参值
        /// </summary>
        /// <param name="paraName">参数名称</param>
        /// <returns></returns>
        public static string GetRequestPara(this System.Web.UI.Page page, string paraName)
        {
            if (paraName != null && paraName != "")
            {
                if (page.Request[paraName] != null && page.Request[paraName].ToString().Trim() != "")
                {
                    return page.Request[paraName];
                }
            }
            return "";
        }


        /// <summary>
        /// 获得传参ID值
        /// </summary>
        /// <param name="paraName">参数名称</param>
        /// <returns></returns>
        public static int GetRequestParaID(this System.Web.UI.Page page, string paraName)
        {
            int ret = 0;
            if (paraName != null && paraName != "")
            {
                if (page.Request[paraName] != null && page.Request[paraName].ToString().Trim() != "")
                {
                    ret = Convert.ToInt32(page.Request[paraName]);
                }
            }
            return ret;
        }

        #region 文件操作


        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="fu">上传控件（ExtAspNet.FileUpload）</param>
        /// <param name="path">目录</param>
        /// <param name="fileName">文件名称</param>
        /// <returns></returns>
        public static string UpLoadFile(this System.Web.UI.Page page, System.Web.UI.WebControls.FileUpload fu, string path, string fileName)
        {
            string PhysicalPath = "";//物理路径
            try
            {
                if (fu.HasFile)
                {
                    PhysicalPath = System.IO.Path.GetDirectoryName(page.Server.MapPath("~/filemanager/UpLoad/") + path);
                    //如果目录不存在
                    if (!System.IO.Directory.Exists(PhysicalPath))
                    {
                        System.IO.Directory.CreateDirectory(PhysicalPath);//创建文件目录
                    }

                    fu.SaveAs(PhysicalPath + "\\" + fileName);
                }

            }
            catch
            {

            }
            return path + fileName;
        }


        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="path">文件路径</param>
        public static void DeleteFile(this System.Web.UI.Page page, string path)
        {
            try
            {
                System.IO.File.Delete(path);
            }
            catch (Exception)
            {


            }

        }

        #endregion

        #endregion

        #region 字段串是否为Null或为""(空)
        /// <summary>
        /// 字段串是否为Null或为""(空)
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool StrIsNullOrEmpty(this string str)
        {
            if (str == null || str.Trim() == string.Empty)
                return true;

            return false;
        }
        #endregion

        #region 全半角转换
        /// <summary>
        /// 转全角(SBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>全角字符串</returns>
        public static string ToSBC(this string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 32)
                {
                    c[i] = (char)12288;
                    continue;
                }
                if (c[i] < 127)
                    c[i] = (char)(c[i] + 65248);
            }
            return new string(c);
        }
        /// <summary>
        /// 转半角(DBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>半角字符串</returns>
        public static string ToDBC(this string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 12288)
                {
                    c[i] = (char)32;
                    continue;
                }
                if (c[i] > 65280 && c[i] < 65375)
                    c[i] = (char)(c[i] - 65248);
            }
            return new string(c);
        }
        #endregion

        #region 自定义的替换字符串函数
        /// <summary>
        /// 自定义的替换字符串函数
        /// </summary>
        /// <param name="SourceString">源字符串</param>
        /// <param name="SearchString">目标字符串</param>
        /// <param name="ReplaceString">要替换成的字符串</param>
        /// <param name="IsCaseInsensetive">是否区分大小写，True区分，False不区分</param>
        /// <returns></returns>
        public static string ReplaceString(this string SourceString, string SearchString, string ReplaceString, bool IsCaseInsensetive)
        {
            return Regex.Replace(SourceString, Regex.Escape(SearchString), ReplaceString, IsCaseInsensetive ? RegexOptions.IgnoreCase : RegexOptions.None);
        }

        /// <summary>
        /// 标签转换函数
        /// </summary>
        /// <param name="aStr">要转换的数据</param>
        /// <param name="aLabel">标签</param>
        /// <param name="aResult">值</param>
        /// <returns></returns>
        public static string GetReplace(this string aStr, string aLabel, string aResult)
        {
            if (aStr == null | string.IsNullOrEmpty(aStr)) return string.Empty;
            if (StrIsNullOrEmpty(aLabel)) return aStr;
            if (aResult != "" | string.IsNullOrEmpty(aResult) == false) return aStr.Replace(aLabel, aResult);
            else return aStr.Replace(aLabel, string.Empty);
        }
        #endregion

    }

}
